function H=load2DHFilter(filename,precision)
    global verbose
    fid=fopen(filename,'r');
    if fid > 0
        n=fread(fid,1,'int');
        timestamp=fread(fid,1,'real*8');
        precond=fread(fid,1,'int');
        if verbose
            fprintf('loading 2D filter which was created on %s for n = %d and precond %d\n',datestr(timestamp),n,precond);
        end
        if strcmp(precision,'single')
            Htmp0=fread(fid,n*(n+1)/2,'real*4');
        elseif strcmp(precision,'double')
            Htmp0=fread(fid,n*(n+1)/2,'real*8');
        else
            error('precision must be single or double');
        end
        fclose(fid);
        Htmp1=zeros(n,precision);
        decn=n:-1:1;
        start_index=zeros(1,n,precision);
        end_index=zeros(1,n,precision);
        for i=1:n
            if i ~= 1
                start_index(i)=start_index(i-1)+decn(i-1);
            else
                start_index(i)=i;
            end
            end_index(i)=(decn(1)+decn(i))*i/2;
        end
        for i=1:n
            Htmp1(i,i:n)=Htmp0(start_index(i):end_index(i));
        end
        % H1 is upper triangular matrix
        Htmp1=Htmp1+Htmp1';
        % when adding H1 with its transpose the diagonal is added twice
        for i=1:n
            Htmp1(i,i)=Htmp1(i,i)/2;
        end
        % append H1 with its reflection to the right
        Htmp2=[Htmp1 fliplr(Htmp1(:,1:n-1))];
        % append H2 with its reflection to the bottom
        H.precond=precond;
        H.filter=[Htmp2 ; flipud(Htmp2(1:n-1,:))];
        % now H is a structure holding the original filter
    else
        error('failed to open file %sfor reading, filter was not loaded\n',filename);
    end
end